package cc.autoapi.pucong.auto.flow.provider.properties.manager;


import cc.autoapi.pucong.auto.flow.core.flow.execNode.exception.AutoDesignException;
import cc.autoapi.pucong.auto.flow.core.root.utils.AESEncryptUtil;
import cc.autoapi.pucong.auto.flow.core.root.utils.UUID;
import cc.autoapi.pucong.auto.flow.persistence.po.properties.PropertiesInfoPo;
import cc.autoapi.pucong.auto.flow.persistence.po.sys.GroupInfoPo;
import cc.autoapi.pucong.auto.flow.persistence.repository.properties.PropertiesInfoService;
import cc.autoapi.pucong.auto.flow.provider.group.service.GroupInfoService;
import cc.autoapi.pucong.auto.flow.provider.properties.entity.PropertiesInfoConvert;
import cc.autoapi.pucong.auto.flow.provider.properties.entity.dto.PropertiesInfoAddDto;
import cc.autoapi.pucong.auto.flow.provider.properties.entity.dto.PropertiesInfoUpdateDto;
import cc.autoapi.pucong.auto.flow.provider.properties.entity.qo.PropertiesInfoQo;
import cc.autoapi.pucong.auto.flow.provider.properties.entity.vo.PropertiesInfoTreeVo;
import cc.autoapi.pucong.auto.flow.provider.properties.entity.vo.PropertiesInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author pucong
 * @description 全局参数信息 managerService 实现类
 * @create 2024-10-06
 */
@Service
@Slf4j
public class PropertiesInfoManager {

    @Resource
    private PropertiesInfoService propertiesInfoService;

    @Resource
    private GroupInfoService groupInfoService;

    public List<PropertiesInfoVo> getList(PropertiesInfoQo qo) {
        List<PropertiesInfoPo> propertiesInfos = propertiesInfoService.list(qo.getGroupId(), qo.getPropertiesCode());
        List<PropertiesInfoVo> propertiesInfoVos = PropertiesInfoConvert.INSTANCE.po2vos(propertiesInfos);
        return propertiesInfoVos;
    }

    public PropertiesInfoVo getDetailById(String id) {
        PropertiesInfoPo propertiesInfo = propertiesInfoService.getById(id);
        PropertiesInfoVo propertiesInfoVo = PropertiesInfoConvert.INSTANCE.po2vo(propertiesInfo);
        return propertiesInfoVo;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String add(PropertiesInfoAddDto dto) {
        // 校验编码是否重复
        long count = propertiesInfoService.getCountByCode(dto.getPropertiesCode());
        if (count > 0) {
            throw new AutoDesignException("编码重复");
        }
        PropertiesInfoPo propertiesInfo = PropertiesInfoConvert.INSTANCE.dto2po(dto);
        String id = UUID.uuid();
        propertiesInfo.setUuid(id);
        propertiesInfo.setCreateTime(new Date());
        if (dto.getNeedEncryption() == 1) {
            String propertiesValue = propertiesInfo.getPropertiesValue();
            // 加密
            propertiesInfo.setPropertiesValue(AESEncryptUtil.encrypt(propertiesValue));
        }
        Boolean i = propertiesInfoService.save(propertiesInfo);
        propertiesInfoService.putCache(propertiesInfo);
        return id;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean updateById(String id, PropertiesInfoUpdateDto dto) {
        // 校验编码是否重复
        long count = propertiesInfoService.getCountByCode(id, dto.getPropertiesCode());
        if (count > 0) {
            throw new AutoDesignException("编码重复");
        }
        PropertiesInfoPo byId = propertiesInfoService.getById(id);
        PropertiesInfoPo propertiesInfoUpdate = PropertiesInfoConvert.INSTANCE.dto2po(dto);
        propertiesInfoUpdate.setUuid(id);
        if ((dto.getNeedEncryption() == 1 && !byId.getPropertiesValue().equals(dto.getPropertiesValue())) || (byId.getNeedEncryption() == 0 && dto.getNeedEncryption() == 1)) {
            String propertiesValue = propertiesInfoUpdate.getPropertiesValue();
            // 加密
            propertiesInfoUpdate.setPropertiesValue(AESEncryptUtil.encrypt(propertiesValue));
        }
        Boolean i = propertiesInfoService.updateById(propertiesInfoUpdate);
        propertiesInfoService.putCache(propertiesInfoUpdate);
        return i;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean batchDeleteByIds(List<String> ids) {
        Boolean i = propertiesInfoService.removeBatchByIds(ids);
        return i;
    }

    public List<PropertiesInfoTreeVo> getTree(PropertiesInfoQo dto) {
        List<PropertiesInfoTreeVo> vos = new ArrayList<>();
        List<PropertiesInfoVo> list = getList(dto);
        if (list.size() > 0) {
            List<String> groupIds = list.stream().map(PropertiesInfoVo::getGroupId).collect(Collectors.toList());
            List<GroupInfoPo> groupInfos = groupInfoService.listByIds(groupIds);
            for (GroupInfoPo groupInfo : groupInfos) {
                PropertiesInfoTreeVo vo = new PropertiesInfoTreeVo();
                vo.setUuid(groupInfo.getUuid());
                vo.setNodeName(groupInfo.getName());
                vo.setTreeType(0);
                vo.setParentId("-1");
                vos.add(vo);
            }
            for (PropertiesInfoVo propertiesInfoVo : list) {
                PropertiesInfoTreeVo vo = new PropertiesInfoTreeVo();
                vo.setUuid(propertiesInfoVo.getPropertiesCode());
                vo.setNodeName(propertiesInfoVo.getPropertiesCode());
                vo.setPropertiesType(propertiesInfoVo.getPropertiesType());
                vo.setPropertiesValue(propertiesInfoVo.getPropertiesValue());
                vo.setPropertiesDesc(propertiesInfoVo.getPropertiesDesc());
                vo.setTreeType(1);
                vo.setParentId(propertiesInfoVo.getGroupId());
                vos.add(vo);
            }
        }
        return vos;
    }

    public List<PropertiesInfoTreeVo> getTree2(PropertiesInfoQo dto) {
        List<PropertiesInfoTreeVo> vos = new ArrayList<>();
        List<PropertiesInfoVo> list = getList(dto);
        if (list.size() > 0) {
            List<String> groupIds = list.stream().map(PropertiesInfoVo::getGroupId).collect(Collectors.toList());
            List<GroupInfoPo> groupInfos = groupInfoService.listByIds(groupIds);
            for (GroupInfoPo groupInfo : groupInfos) {
                PropertiesInfoTreeVo vo = new PropertiesInfoTreeVo();
                vo.setUuid(groupInfo.getUuid());
                vo.setNodeName(groupInfo.getName());
                vo.setTreeType(0);
                vo.setParentId("-1");
                vos.add(vo);
            }
            for (PropertiesInfoVo propertiesInfoVo : list) {
                PropertiesInfoTreeVo vo = new PropertiesInfoTreeVo();
                vo.setUuid(propertiesInfoVo.getUuid());
                vo.setNodeName(propertiesInfoVo.getPropertiesCode());
                vo.setPropertiesType(propertiesInfoVo.getPropertiesType());
                vo.setPropertiesValue(propertiesInfoVo.getPropertiesValue());
                vo.setPropertiesDesc(propertiesInfoVo.getPropertiesDesc());
                vo.setTreeType(1);
                vo.setParentId(propertiesInfoVo.getGroupId());
                vos.add(vo);
            }
        }
        return vos;
    }
}
